<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Section 10.14.&nbsp; sigaction Function</title>
<link rel="STYLESHEET" type="text/css" href="images/style.css">
<link rel="STYLESHEET" type="text/css" href="images/docsafari.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch10lev1sec13.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch10lev1sec15.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
<br><table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td valign="top"><a name="ch10lev1sec14"></a>
<h3 class="docSection1Title">10.14. <tt>sigaction</tt> Function</h3>
<p class="docText">The <tt>sigaction</tt> function allows us to examine or modify (or both) the action associated with a particular signal. This function supersedes the <tt>signal</tt> function from earlier releases of the UNIX System. Indeed, at the end of this section, we show an implementation of <tt>signal</tt> using <tt>sigaction</tt>.</P>
<a name="inta313"></a><P><table cellspacing="0" class="allBorders" border="1" RULES="none" cellpadding="5"><colgroup><col width="500"></colgroup><thead></thead><tr><TD class="docTableCell" align="left" valign="top"><p class="docText">
<a name="PLID0"></a><div class="v1"><a href="ch10lev1sec14.html#PLID0">[View full width]</a></div><pre>
#include &lt;signal.h&gt;

int sigaction(int <span class="docEmphItalicAlt">signo</span>, const struct sigaction
<img border="0" width="14" height="9" alt="" align="left" src="images/ccc.gif"> *restrict <span class="docEmphItalicAlt">act</span>,
              struct sigaction *restrict <span class="docEmphItalicAlt">oact</span>);
</pre><BR>

</P></td></TR><TR><TD class="docTableCell" align="right" valign="top"><p class="docText">Returns: 0 if OK, 1 on error</p></TD></tr></table></P><BR>
<p class="docText">The argument <span class="docEmphasis">signo</span> is the signal number whose action we are examining or modifying. If the <span class="docEmphasis">act</span> pointer is non-null, we are modifying the action. If the <span class="docEmphasis">oact</span> pointer is non-null, the system returns the previous action for the signal through the <span class="docEmphasis">oact</span> pointer. This function uses the following structure:</P>

<pre>
     struct sigaction {
       void      (*sa_handler)(int);   /* addr of signal handler, */
                                       /* or SIG_IGN, or SIG_DFL */
       sigset_t sa_mask;               /* additional signals to block */
       int      sa_flags;              /* signal options, Figure 10.16 */

       /* alternate handler */
       void     (*sa_sigaction)(int, siginfo_t *, void *);
    };
</pre><br>

<p class="docText"><a name="idd1e75863"></a><a name="idd1e75868"></a><a name="idd1e75873"></a><a name="idd1e75878"></a><a name="idd1e75883"></a>When changing the action for a signal, if the <tt>sa_handler</tt> field contains the address of a signal-catching function (as opposed to the constants <tt>SIG_IGN</tt> or <tt>SIG_DFL</tt>), then the <tt>sa_mask</tt> field specifies a set of signals that are added to the signal mask of the process before the signal-catching function is called. If and when the signal-catching function returns, the signal mask of the process is reset to its previous value. This way, we are able to block certain signals whenever a signal handler is invoked. The operating system includes the signal being delivered in the signal mask when the handler is invoked. Hence, we are guaranteed that whenever we are processing a given signal, another occurrence of that same signal is blocked until we're finished processing the first occurrence. Recall from <a class="docLink" href="ch10lev1sec8.html#ch10lev1sec8">Section 10.8</a> that additional occurrences of the same signal are usually not queued. If the signal occurs five times while it is blocked, when we unblock the signal, the signal-handling function for that signal will usually be invoked only one time.</P>
<p class="docText">Once we install an action for a given signal, that action remains installed until we explicitly change it by calling <tt>sigaction</tt>. Unlike earlier systems with their unreliable signals, POSIX.1 requires that a signal handler remain installed until explicitly changed.</P>
<p class="docText">The <tt>sa_flags</tt> field of the <span class="docEmphasis">act</span> structure specifies various options for the handling of this signal. <a class="docLink" href="#ch10fig16">Figure 10.16</a> details the meaning of these options when set. The SUS column contains &#8226; if the flag is defined as part of the base POSIX.1 specification, and <span class="docEmphStrong">XSI</span> if it is defined as an XSI extension to the base.</p>
<a name="ch10fig16"></a><P><table cellspacing="0" class="allBorders" border="1" RULES="groups" cellpadding="5"><caption><H5 class="docTableTitle">Figure 10.16. Option flags (<tt>sa_flags</tt>) for the handling of each signal</h5></caption><colgroup><col width="75"><col width="50"><col width="50"><col width="50"><col width="50"><col width="50"><col width="175"></colgroup><thead><tr><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="middle"><p class="docText"><a name="idd1e75958"></a><a name="idd1e75963"></a><a name="idd1e75968"></a><a name="idd1e75971"></a><a name="idd1e75974"></a><a name="idd1e75977"></a><a name="idd1e75980"></a><a name="idd1e75983"></a><a name="idd1e75988"></a><a name="idd1e75993"></a><a name="idd1e75998"></a><a name="idd1e76003"></a><a name="idd1e76008"></a><a name="idd1e76013"></a><a name="idd1e76018"></a><a name="idd1e76023"></a><a name="idd1e76028"></a><a name="idd1e76033"></a><a name="idd1e76038"></a><a name="idd1e76043"></a><a name="idd1e76046"></a><a name="idd1e76051"></a><a name="idd1e76056"></a><a name="idd1e76061"></a><span class="docEmphRoman">Option</span></p></th><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">SUS</span></p></th><th class="bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">FreeBSD 5.2.1</span></P></th><th class="bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">Linux 2.4.22</span></p></th><th class="bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">Mac OS X 10.3</span></P></th><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="bottom"><p class="docText"><span class="docEmphRoman">Solaris 9</span></p></th><th class="bottomBorder thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">Description</span></P></th></tr></thead><tr><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SA_INTERRUPT</tt></p></td><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="docTableCell" align="left" valign="top">&nbsp;</td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="docTableCell" align="left" valign="top"><p class="docText">System calls interrupted by this signal are not automatically restarted (the XSI default for <tt>sigaction</tt>). See <a class="docLink" href="ch10lev1sec5.html#ch10lev1sec5">Section 10.5</a> for more information.
</P></TD></tr><TR><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>SA_NOCLDSTOP</tt></P></td><TD class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</P></TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></TD><td class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</P></TD><td class="docTableCell" align="left" valign="top"><p class="docText">If <span class="docEmphasis">signo</span> is <tt>SIGCHLD</tt>, do not generate this signal when a child process stops (job control). This signal is still generated, of course, when a child terminates (but see the <tt>SA_NOCLDWAIT</tt> option below). As an XSI extension, <tt>SIGCHLD</tt> won't be sent when a stopped child continues if this flag is set.
</p></td></tr><TR><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SA_NOCLDWAIT</tt></P></td><TD class="rightBorder" align="left" valign="top"><p class="docText">XSI</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="left" valign="top"><p class="docText">If <span class="docEmphasis">signo</span> is <tt>SIGCHLD</tt>, this option prevents the system from creating zombie processes when children of the calling process terminate. If it subsequently calls <tt>wait</tt>, the calling process blocks until all its child processes have terminated and then returns 1 with <tt>errno</tt> set to <tt>ECHILD</tt>. (Recall <a class="docLink" href="ch10lev1sec7.html#ch10lev1sec7">Section 10.7</a>.)</p></td></TR><TR><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SA_NODEFER</tt></P></TD><TD class="rightBorder" align="left" valign="top"><p class="docText">XSI</p></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><TD class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="left" valign="top"><p class="docText">When this signal is caught, the signal is not automatically blocked by the system while the signal-catching function executes (unless the signal is also included in <tt>sa_mask</tt>). Note that this type of operation corresponds to the earlier unreliable signals.</P></td></tr><tr><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SA_ONSTACK</tt></P></td><TD class="rightBorder" align="left" valign="top"><p class="docText">XSI</p></TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="left" valign="top"><p class="docText">If an alternate stack has been declared with <tt>sigaltstack</tt>(2), this signal is delivered to the process on the alternate stack.</p></td></tr><tr><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>SA_RESETHAND</tt></P></td><TD class="rightBorder" align="left" valign="top"><p class="docText">XSI</P></TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></TD><TD class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</p></TD><TD class="docTableCell" align="left" valign="top"><p class="docText">The disposition for this signal is reset to <tt>SIG_DFL</tt>, and the <tt>SA_SIGINFO</tt> flag is cleared on entry to the signal-catching function. Note that this type of operation corresponds to the earlier unreliable signals. The disposition for the two signals <tt>SIGILL</tt> and <tt>SIGTRAP</tt> can't be reset automatically, however. Setting this flag causes <tt>sigaction</tt> to behave as if <tt>SA_NODEFER</tt> is also set.
</p></TD></TR><tr><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SA_RESTART</tt></p></td><TD class="rightBorder" align="left" valign="top"><p class="docText">XSI</p></TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</p></td><td class="docTableCell" align="left" valign="top"><p class="docText">System calls interrupted by this signal are automatically restarted. (Refer to <a class="docLink" href="ch10lev1sec5.html#ch10lev1sec5">Section 10.5</a>.)
</p></td></tr><tr><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SA_SIGINFO</tt></p></TD><TD class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</p></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><TD class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></TD><td class="docTableCell" align="center" valign="top"><p class="docText">&#8226;</P></td><TD class="rightBorder" align="center" valign="top"><p class="docText">&#8226;</P></TD><td class="docTableCell" align="left" valign="top"><p class="docText">This option provides additional information to a signal handler: a pointer to a <tt>siginfo</tt> structure and a pointer to an identifier for the process context.</P></TD></tr></table></P><BR>
<p class="docText">The <tt>sa_sigaction</tt> field is an alternate signal handler used when the <tt>SA_SIGINFO</tt> flag is used with <tt>sigaction</tt>. Implementations might use the same storage for both the <tt>sa_sigaction</tt> field and the <tt>sa_handler</tt> field, so applications can use only one of these fields at a time.</p>
<p class="docText">Normally, the signal handler is called as</p>

<pre>
   void handler(int <span class="docEmphItalicAlt">signo</span>);
</pre><br>

<p class="docText">but if the <tt>SA_SIGINFO</tt> flag is set, the signal handler is called as</p>

<pre>
   void handler(int <span class="docEmphItalicAlt">signo</span>, siginfo_t *<span class="docEmphItalicAlt">info</span>, void *<span class="docEmphItalicAlt">context</span>);
</pre><BR>

<p class="docText">The <tt>siginfo_t</tt> structure contains information about why the signal was generated. An example of what it might look like is shown below. All POSIX.1-compliant implementations must include at least the <tt>si_signo</tt> and <tt>si_code</tt> members. Additionally, implementations that are XSI compliant contain at least the following fields:</p>

<pre>
    struct siginfo {
      int    si_signo;  /* signal number */
      int    si_errno;  /* if nonzero, errno value from &lt;errno.h&gt; */
      int    si_code;   /* additional info (depends on signal) */
      pid_t  si_pid;    /* sending process ID */
      uid_t  si_uid;    /* sending process real user ID */
      void  *si_addr;   /* address that caused the fault */
      int    si_status; /* exit value or signal number */
      long   si_band;   /* band number for SIGPOLL */
      /* possibly other fields also */
    };
</pre><BR>

<p class="docText"><a name="idd1e76474"></a><a name="idd1e76479"></a><a name="idd1e76484"></a><a name="idd1e76489"></a><a name="idd1e76494"></a><a name="idd1e76499"></a><a name="idd1e76504"></a><a name="idd1e76509"></a><a name="idd1e76514"></a><a name="idd1e76519"></a><a name="idd1e76524"></a><a name="idd1e76529"></a><a name="idd1e76534"></a><a name="idd1e76539"></a><a name="idd1e76544"></a><a name="idd1e76549"></a><a name="idd1e76554"></a><a name="idd1e76559"></a><a name="idd1e76564"></a><a name="idd1e76569"></a><a name="idd1e76574"></a><a name="idd1e76579"></a><a name="idd1e76584"></a><a name="idd1e76589"></a><a name="idd1e76594"></a><a name="idd1e76599"></a><a name="idd1e76604"></a><a name="idd1e76609"></a><a name="idd1e76614"></a><a name="idd1e76619"></a><a name="idd1e76624"></a><a name="idd1e76629"></a><a name="idd1e76634"></a><a name="idd1e76639"></a><a name="idd1e76644"></a><a name="idd1e76649"></a><a name="idd1e76654"></a><a name="idd1e76659"></a><a name="idd1e76664"></a><a name="idd1e76669"></a><a name="idd1e76674"></a><a name="idd1e76679"></a><a name="idd1e76684"></a><a name="idd1e76689"></a><a name="idd1e76694"></a><a name="idd1e76697"></a><a name="idd1e76702"></a><a name="idd1e76707"></a><a class="docLink" href="#ch10fig17">Figure 10.17</a> shows values of <tt>si_code</tt> for various signals, as defined by the Single UNIX Specification. Note that implementations may define additional code values.</p>
<a name="ch10fig17"></a><P><table cellspacing="0" class="allBorders" border="1" RULES="groups" cellpadding="5"><caption><h5 class="docTableTitle">Figure 10.17. <tt>siginfo_t</tt> code values</h5></caption><colgroup><col width="100"><col width="100"><col width="300"></colgroup><thead><tr><th class="rightBorder bottomBorder thead" scope="col" align="left" valign="top"><p class="docText"><span class="docEmphRoman">Signal</span></p></th><th class="rightBorder bottomBorder thead" scope="col" align="left" valign="top"><p class="docText"><span class="docEmphRoman">Code</span></p></th><th class="rightBorder bottomBorder thead" scope="col" align="left" valign="top"><p class="docText"><span class="docEmphRoman">Reason</span></p></th></tr></thead><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>ILL_ILLOPC</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">illegal opcode</p></td></tr><TR><TD class="rightBorder" align="left" valign="top">&nbsp;</td><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>ILL_ILLOPN</tt></P></TD><td class="rightBorder" align="left" valign="top"><p class="docText">illegal operand</P></TD></TR><tr><TD class="rightBorder" align="left" valign="top">&nbsp;</td><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>ILL_ILLADR</tt></P></TD><td class="rightBorder" align="left" valign="top"><p class="docText">illegal addressing mode</P></TD></tr><TR><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>SIGILL</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>ILL_ILLTRP</tt></p></TD><td class="rightBorder" align="left" valign="top"><p class="docText">illegal trap</P></td></TR><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>ILL_PRVOPC</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">privileged opcode</p></td></tr><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>ILL_PRVREG</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">privileged register</P></TD></tr><TR><TD class="rightBorder" align="left" valign="top">&nbsp;</TD><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>ILL_COPROC</tt></P></TD><TD class="rightBorder" align="left" valign="top"><p class="docText">coprocessor error</p></TD></tr><TR><TD class="rightBorder bottomBorder" align="left" valign="top">&nbsp;</TD><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText"><tt>ILL_BADSTK</tt></P></TD><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText">internal stack error
</P></TD></tr><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>FPE_INTDIV</tt></p></TD><td class="rightBorder" align="left" valign="top"><p class="docText">integer divide by zero</P></td></tr><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>FPE_INTOVF</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">integer overflow</p></td></tr><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>FPE_FLTDIV</tt></p></TD><TD class="rightBorder" align="left" valign="top"><p class="docText">floating-point divide by zero</p></TD></TR><TR><td class="rightBorder" align="left" valign="top">&nbsp;</TD><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>FPE_FLTOVF</tt></P></td><TD class="rightBorder" align="left" valign="top"><p class="docText">floating-point overflow</p></TD></TR><TR><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SIGFPE</tt></P></TD><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>FPE_FLTUND</tt></P></TD><td class="rightBorder" align="left" valign="top"><p class="docText">floating-point underflow</p></td></tr><TR><td class="rightBorder" align="left" valign="top">&nbsp;</TD><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>FPE_FLTRES</tt></P></td><td class="rightBorder" align="left" valign="top"><p class="docText">floating-point inexact result</p></td></tr><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>FPE_FLTINV</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">invalid floating-point operation</p></td></tr><tr><td class="rightBorder bottomBorder" align="left" valign="top">&nbsp;</TD><TD class="rightBorder bottomBorder" align="left" valign="top"><p class="docText"><tt>FPE_FLTSUB</tt></p></TD><TD class="rightBorder bottomBorder" align="left" valign="top"><p class="docText">subscript out of range
</P></td></TR><TR><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>SIGSEGV</tt></p></TD><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SEGV_MAPERR</tt></P></TD><TD class="rightBorder" align="left" valign="top"><p class="docText">address not mapped to object</p></TD></TR><tr><TD class="rightBorder bottomBorder" align="left" valign="top">&nbsp;</TD><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText"><tt>SEGV_ACCERR</tt></p></td><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText">invalid permissions for mapped object
</P></td></TR><tr><TD class="rightBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>BUS_ADRALN</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">invalid address alignment</p></td></tr><tr><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SIGBUS</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>BUS_ADRERR</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">nonexistent physical address</p></TD></TR><tr><TD class="rightBorder bottomBorder" align="left" valign="top">&nbsp;</TD><TD class="rightBorder bottomBorder" align="left" valign="top"><p class="docText"><tt>BUS_OBJERR</tt></p></TD><TD class="rightBorder bottomBorder" align="left" valign="top"><p class="docText">object-specific hardware error
</P></td></TR><tr><TD class="rightBorder" align="left" valign="top">&nbsp;</TD><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>trAP_BRKPT</tt></P></TD><td class="rightBorder" align="left" valign="top"><p class="docText">process breakpoint trap</P></TD></tr><tr><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText"><tt>SIGTRAP</tt></p></TD><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText"><tt>TRAP_TRACE</tt></p></TD><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText">process trace trap
</p></td></tr><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>CLD_EXITED</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">child has exited</p></td></tr><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>CLD_KILLED</tt></P></td><TD class="rightBorder" align="left" valign="top"><p class="docText">child has terminated abnormally (no core)</P></TD></tr><TR><TD class="rightBorder" align="left" valign="top">&nbsp;</TD><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>CLD_DUMPED</tt></P></td><TD class="rightBorder" align="left" valign="top"><p class="docText">child has terminated abnormally with core</P></TD></tr><TR><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>SIGCHLD</tt></p></TD><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>CLD_TRAPPED</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">traced child has trapped</p></TD></tr><TR><td class="rightBorder" align="left" valign="top">&nbsp;</TD><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>CLD_STOPPED</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">child has stopped</p></td></tr><tr><td class="rightBorder bottomBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText"><tt>CLD_CONTINUED</tt></p></td><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText">stopped child has continued
</p></td></tr><TR><TD class="rightBorder" align="left" valign="top">&nbsp;</td><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>POLL_IN</tt></P></TD><td class="rightBorder" align="left" valign="top"><p class="docText">data can be read</P></TD></TR><tr><TD class="rightBorder" align="left" valign="top">&nbsp;</td><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>POLL_OUT</tt></P></TD><td class="rightBorder" align="left" valign="top"><p class="docText">data can be written</P></TD></tr><TR><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>SIGPOLL</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>POLL_MSG</tt></p></TD><td class="rightBorder" align="left" valign="top"><p class="docText">input message available</P></td></TR><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>POLL_ERR</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">I/O error</p></td></tr><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>POLL_PRI</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">high-priority message available</P></TD></tr><TR><TD class="rightBorder bottomBorder" align="left" valign="top">&nbsp;</TD><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText"><tt>POLL_HUP</tt></P></TD><TD class="rightBorder bottomBorder" align="left" valign="top"><p class="docText">device disconnected
</p></TD></tr><TR><TD class="rightBorder" align="left" valign="top">&nbsp;</TD><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SI_USER</tt></P></TD><td class="rightBorder" align="left" valign="top"><p class="docText">signal sent by kill</P></TD></tr><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>SI_QUEUE</tt></p></TD><td class="rightBorder" align="left" valign="top"><p class="docText">signal sent by <tt>sigqueue</tt> (real-time extension)</P></td></tr><tr><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>Any</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SI_TIMER</tt></p></td><td class="rightBorder" align="left" valign="top"><p class="docText">expiration of a timer set by <tt>timer_settime</tt> (real-time extension)</p></td></tr><tr><td class="rightBorder" align="left" valign="top">&nbsp;</td><td class="rightBorder" align="left" valign="top"><p class="docText"><tt>SI_ASYNCIO</tt></P></TD><td class="rightBorder" align="left" valign="top"><p class="docText">completion of asynchronous I/O request (real-time extension)</P></TD></TR><tr><TD class="rightBorder" align="left" valign="top">&nbsp;</TD><TD class="rightBorder" align="left" valign="top"><p class="docText"><tt>SI_MESGQ</tt></p></TD><td class="rightBorder" align="left" valign="top"><p class="docText">arrival of a message on a message queue (real-time extension)</P></TD></TR></table></p><BR>
<p class="docText">If the signal is <tt>SIGCHLD</tt>, then the <tt>si_pid</tt>, <tt>si_status</tt>, and <tt>si_uid</tt> field will be set. If the signal is <tt>SIGILL</tt> or <tt>SIGSEGV</tt>, then the <tt>si_addr</tt> contains the address responsible for the fault, although the address might not be accurate. If the signal is <tt>SIGPOLL</tt>, then the <tt>si_band</tt> field will contain the priority band for STREAMS <a name="idd1e77380"></a><a name="idd1e77385"></a><a name="idd1e77390"></a><a name="idd1e77395"></a><a name="idd1e77400"></a><a name="idd1e77405"></a><a name="idd1e77410"></a><a name="idd1e77415"></a><a name="idd1e77420"></a><a name="idd1e77425"></a><a name="idd1e77430"></a><a name="idd1e77435"></a><a name="idd1e77440"></a><a name="idd1e77447"></a><a name="idd1e77450"></a>messages that generate the <tt>POLL_IN</tt>, <tt>POLL_OUT</tt>, or <tt>POLL_MSG</tt> events. (For a complete discussion of priority bands, see Rago [<a class="docLink" href="bib01.html#biblio01_052">1993</a>].) The <tt>si_errno</tt> field contains the error number corresponding to the condition that caused the signal to be generated, although its use is implementation defined.</P>
<p class="docText">The <span class="docEmphasis">context</span> argument to the signal handler is a typeless pointer that can be cast to a <tt>ucontext_t</tt> structure identifying the process context at the time of signal delivery.</p>
<blockquote>
<p class="docText">When an implementation supports the real-time signal extensions, signal handlers established with the <tt>SA_SIGINFO</tt> flag will result in signals being queued reliably. A separate range of reserved signals is available for real-time application use. The <tt>siginfo</tt> structure can contain application-specific data if the signal is generated by <tt>sigqueue</tt>. We do not discuss the real-time extensions further. Refer to Gallmeister [<a class="docLink" href="bib01.html#biblio01_020">1995</a>] for more details.</P>
</blockquote>
<a name="ch10ex10"></a>
<H5 class="docExampleTitle">Example<tt>signal</tt> Function</h5>
<p class="docText">Let's now implement the <tt>signal</tt> function using <tt>sigaction</tt>. This is what many platforms do (and what a note in the POSIX.1 Rationale states was the intent of POSIX). Systems with binary compatibility constraints, on the other hand, might provide a <tt>signal</tt> function that supports the older, unreliable-signal semantics. Unless you specifically require these older, unreliable semantics (for backward compatibility), you should use the following implementation of <tt>signal</tt> or call <tt>sigaction</tt> directly. (As you might guess, an implementation of <tt>signal</tt> with the old semantics could call <tt>sigaction</tt> specifying <tt>SA_RESETHAND</tt> and <tt>SA_NODEFER</tt>.) All the examples in this text that call <tt>signal</tt> call the function shown in <a class="docLink" href="#ch10fig18">Figure 10.18</a>.</p>
<p class="docText"><a name="idd1e77546"></a><a name="idd1e77549"></a><a name="idd1e77552"></a><a name="idd1e77555"></a><a name="idd1e77560"></a><a name="idd1e77563"></a><a name="idd1e77566"></a><a name="idd1e77571"></a><a name="idd1e77576"></a><a name="idd1e77581"></a><a name="idd1e77588"></a><a name="idd1e77593"></a><a name="idd1e77596"></a><a name="idd1e77599"></a><a name="idd1e77604"></a><a name="idd1e77609"></a>Note that we must use <tt>sigemptyset</tt> to initialize the <tt>sa_mask</tt> member of the structure. We're not guaranteed that</p>

<pre>
    act.sa_mask = 0;
</pre><br>

<p class="docText">does the same thing.</P>
<p class="docText">We intentionally try to set the <tt>SA_RESTART</tt> flag for all signals other than <tt>SIGALRM</tt>, so that any system call interrupted by these other signals is automatically restarted. The reason we don't want <tt>SIGALRM</tt> restarted is to allow us to set a timeout for I/O operations. (Recall the discussion of <a class="docLink" href="ch10lev1sec10.html#ch10fig10">Figure 10.10</a>.)</p>
<p class="docText">Some older systems, such as SunOS, define the <tt>SA_INTERRUPT</tt> flag. These systems restart interrupted system calls by default, so specifying this flag causes system calls to be interrupted. Linux defines the <tt>SA_INTERRUPT</tt> flag for compatibility with applications that use it, but the default is to not restart system calls when the signal handler is installed with <tt>sigaction</tt>. The XSI extension of the Single UNIX Specification specifies that the <tt>sigaction</tt> function not restart interrupted system calls unless the <tt>SA_RESTART</tt> flag is specified.</P>

<a name="ch10fig18"></a>
<h5 class="docExampleTitle">Figure 10.18. An implementation of <tt>signal</tt> using <tt>sigaction</tt></H5>

<pre>
#include "apue.h"

/* Reliable version of signal(), using POSIX sigaction(). */
Sigfunc *
signal(int signo, Sigfunc *func)
{
    struct sigaction    act, oact;

    act.sa_handler = func;
    sigemptyset(&amp;act.sa_mask);
    act.sa_flags = 0;
    if (signo == SIGALRM) {
#ifdef SA_INTERRUPT
       act.sa_flags |= SA_INTERRUPT;
#endif
    } else {
#ifdef  SA_RESTART
        act.sa_flags |= SA_RESTART;
#endif
    }
    if (sigaction(signo, &amp;act, &amp;oact) &lt; 0)
        return(SIG_ERR);
    return(oact.sa_handler);
}
</pre><br>


<a name="ch10ex11"></a>
<h5 class="docExampleTitle">Example<tt>signal_intr</tt> Function</h5>
<p class="docText"><a class="docLink" href="#ch10fig19">Figure 10.19</a> shows a version of the <tt>signal</tt> function that tries to prevent any interrupted system calls from being restarted.</p>
<p class="docText">For improved portability, we specify the <tt>SA_INTERRUPT</tt> flag, if defined by the system, to prevent interrupted system calls from being restarted.</p>

<a name="ch10fig19"></a>
<h5 class="docExampleTitle">Figure 10.19. The <tt>signal_intr</tt> function</h5>

<pre>
#include "apue.h"

Sigfunc *
signal_intr(int signo, Sigfunc *func)
{
    struct sigaction    act, oact;

    act.sa_handler = func;
    sigemptyset(&amp;act.sa_mask);
    act.sa_flags = 0;
#ifdef  SA_INTERRUPT
    act.sa_flags |= SA_INTERRUPT;
#endif
    if (sigaction(signo, &amp;act, &amp;oact) &lt; 0)
        return(SIG_ERR);
    return(oact.sa_handler);
}
</pre><br>



<a href="17021535.html"><img src="images/pixel.gif" alt="" width="1" height="1" border="0"></a><ul></ul></td></tr></table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch10lev1sec13.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch10lev1sec15.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
</body></html><br>
<table width="100%" cellspacing="0" cellpadding="0"
style="margin-top: 0pt; border-collapse: collapse;"> 
<tr> <td align="right" style="background-color=white; border-top: 1px solid gray;"> 
<a href="http://www.zipghost.com/" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">The CHM file was converted to HTM by Trial version of <b>ChmD<!--53-->ecompiler</b>.</a>
</TD>
</TR><tr>
<td align="right" style="background-color=white; "> 
<a href="http://www.etextwizard.com/download/cd/cdsetup.exe" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">Download <b>ChmDec<!--53-->ompiler</b> at: http://www.zipghost.com</a>
</TD></tr></table>
